/**
 * 语音引擎 - 处理WebRTC语音聊天的核心逻辑
 * 支持开发环境模拟和生产环境真实音频
 */

class VoiceEngine {
  constructor() {
    this.isProduction = process.env.NODE_ENV === 'production';
    this.isDevelopment = process.env.NODE_ENV === 'development';
    
    // WebRTC配置
    this.rtcConfig = {
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' },
        { urls: 'stun:stun2.l.google.com:19302' }
      ]
    };
    
    // 房间级别的连接管理
    this.roomConnections = new Map(); // roomId -> Map(playerId -> RTCPeerConnection)
    this.currentRooms = new Set(); // 当前加入的房间列表
    this.localStream = null;
    this.roomStreams = new Map(); // roomId -> Map(playerId -> MediaStream)
    
    // 音频分析
    this.audioContext = null;
    this.localAnalyser = null;
    this.microphoneGainNode = null;
    
    // 状态管理
    this.isMicrophoneEnabled = false;
    this.isSpeaking = false;
    this.roomConnectionQualities = new Map(); // roomId -> Map(playerId -> quality info)
    this.currentPlayerId = null; // 当前玩家ID，由外部设置
    
    // 向后兼容的全局连接映射（用于老代码的过渡）
    this.peerConnections = new Map(); // playerId -> RTCPeerConnection (主要房间的连接)
    this.remoteStreams = new Map(); // playerId -> MediaStream (主要房间的流)
    this.connectionQualities = new Map(); // playerId -> quality info (主要房间的质量)
    
    // 事件回调
    this.onSpeakingStateChanged = null;
    this.onConnectionQualityChanged = null;
    this.onRemoteStreamReceived = null;
    this.onConnectionStateChanged = null;
    
    // 房间级别的事件回调
    this.onRoomStreamReceived = null; // (roomId, playerId, stream) => {}
    this.onRoomConnectionStateChanged = null; // (roomId, playerId, state) => {}
    this.onRoomJoined = null; // (roomId) => {}
    this.onRoomLeft = null; // (roomId) => {}
    
    // 模拟相关
    this.simulationTimers = new Map();
    this.simulatedSpeakingUsers = new Set();
    
    this.initializeAudioContext();
  }
  
  /**
   * 初始化音频上下文
   */
  async initializeAudioContext() {
    try {
      // 创建音频上下文
      this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      
      if (this.isDevelopment) {
        console.log('🎤 语音引擎初始化 - 开发模式（模拟音频）');
        await this.initializeSimulatedAudio();
      } else {
        console.log('🎤 语音引擎初始化 - 生产模式（真实音频）');
        await this.initializeRealAudio();
      }
    } catch (error) {
      console.error('音频上下文初始化失败:', error);
      throw error;
    }
  }
  
  /**
   * 初始化真实音频（生产环境）
   */
  async initializeRealAudio() {
    try {
      // 获取用户麦克风权限
      this.localStream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
          sampleRate: 44100
        }
      });
      
      // 创建音频分析节点
      const source = this.audioContext.createMediaStreamSource(this.localStream);
      this.localAnalyser = this.audioContext.createAnalyser();
      this.localAnalyser.fftSize = 256;
      
      // 创建增益节点用于音量控制
      this.microphoneGainNode = this.audioContext.createGain();
      
      // 连接音频节点
      source.connect(this.localAnalyser);
      source.connect(this.microphoneGainNode);
      
      // 开始监控说话状态
      this.startSpeakingDetection();
      
      console.log('✅ 真实音频初始化成功');
    } catch (error) {
      console.error('真实音频初始化失败:', error);
      throw error;
    }
  }
  
  /**
   * 初始化模拟音频（开发环境）
   */
  async initializeSimulatedAudio() {
    try {
      // 创建模拟的音频流
      this.localStream = await this.createSimulatedAudioStream();
      
      // 创建模拟的音频分析
      this.localAnalyser = this.audioContext.createAnalyser();
      this.localAnalyser.fftSize = 256;
      
      // 创建增益节点
      this.microphoneGainNode = this.audioContext.createGain();
      
      // 开始模拟说话状态检测
      this.startSimulatedSpeakingDetection();
      
      console.log('✅ 模拟音频初始化成功');
    } catch (error) {
      console.error('模拟音频初始化失败:', error);
      throw error;
    }
  }
  
  /**
   * 创建模拟的音频流
   */
  async createSimulatedAudioStream() {
    // 创建一个静默的音频轨道
    const audioContext = new AudioContext();
    const oscillator = audioContext.createOscillator();
    const gainNode = audioContext.createGain();
    const destination = audioContext.createMediaStreamDestination();
    
    // 设置为静默
    gainNode.gain.setValueAtTime(0, audioContext.currentTime);
    
    // 连接节点
    oscillator.connect(gainNode);
    gainNode.connect(destination);
    
    // 启动振荡器
    oscillator.start();
    
    // 返回媒体流
    return destination.stream;
  }
  
  /**
   * 开始真实的说话状态检测
   */
  startSpeakingDetection() {
    const bufferLength = this.localAnalyser.frequencyBinCount;
    const dataArray = new Uint8Array(bufferLength);
    
    const detectSpeaking = () => {
      if (!this.localAnalyser) return;
      
      this.localAnalyser.getByteFrequencyData(dataArray);
      
      // 计算平均音量
      const average = dataArray.reduce((sum, value) => sum + value, 0) / bufferLength;
      
      // 说话阈值检测
      const speakingThreshold = 30; // 可调节的阈值
      const wasSpeaking = this.isSpeaking;
      this.isSpeaking = average > speakingThreshold && this.isMicrophoneEnabled;
      
      // 状态变化时触发回调
      if (wasSpeaking !== this.isSpeaking && this.onSpeakingStateChanged) {
        this.onSpeakingStateChanged(this.isSpeaking);
      }
      
      // 继续检测
      requestAnimationFrame(detectSpeaking);
    };
    
    detectSpeaking();
  }
  
  /**
   * 开始模拟的说话状态检测
   */
  startSimulatedSpeakingDetection() {
    // 模拟随机说话状态
    const simulateRandomSpeaking = () => {
      if (!this.isMicrophoneEnabled) {
        this.isSpeaking = false;
        return;
      }
      
      // 30%概率开始说话，70%概率停止说话
      const shouldSpeak = Math.random() < (this.isSpeaking ? 0.3 : 0.1);
      
      if (shouldSpeak !== this.isSpeaking) {
        this.isSpeaking = shouldSpeak;
        
        if (this.onSpeakingStateChanged) {
          this.onSpeakingStateChanged(this.isSpeaking);
        }
        
        // 如果开始说话，设置随机持续时间
        if (this.isSpeaking) {
          const duration = 2000 + Math.random() * 4000; // 2-6秒
          setTimeout(() => {
            if (this.isSpeaking) {
              this.isSpeaking = false;
              if (this.onSpeakingStateChanged) {
                this.onSpeakingStateChanged(false);
              }
            }
          }, duration);
        }
      }
    };
    
    // 每1.5秒检查一次
    setInterval(simulateRandomSpeaking, 1500);
  }
  
  /**
   * 启用/禁用麦克风
   */
  setMicrophoneEnabled(enabled) {
    this.isMicrophoneEnabled = enabled;
    
    if (this.localStream) {
      // 控制音频轨道的启用状态
      this.localStream.getAudioTracks().forEach(track => {
        track.enabled = enabled;
      });
    }
    
    if (this.microphoneGainNode) {
      // 控制音频增益
      this.microphoneGainNode.gain.setValueAtTime(
        enabled ? 1 : 0,
        this.audioContext.currentTime
      );
    }
    
    // 如果禁用麦克风，立即停止说话状态
    if (!enabled && this.isSpeaking) {
      this.isSpeaking = false;
      if (this.onSpeakingStateChanged) {
        this.onSpeakingStateChanged(false);
      }
    }
    
    console.log(`🎤 麦克风${enabled ? '已启用' : '已禁用'}`);
  }
  
  /**
   * 设置麦克风音量
   */
  setMicrophoneVolume(volume) {
    if (this.microphoneGainNode) {
      // volume范围: 0-1
      this.microphoneGainNode.gain.setValueAtTime(
        volume,
        this.audioContext.currentTime
      );
    }
  }
  
  /**
   * 创建到指定玩家的P2P连接
   */
  async createPeerConnection(playerId, isInitiator = false) {
    try {
      // 创建RTCPeerConnection
      const peerConnection = new RTCPeerConnection(this.rtcConfig);
      
      // 添加本地音频流
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => {
          peerConnection.addTrack(track, this.localStream);
        });
      }
      
      // 处理远程音频流
      peerConnection.ontrack = (event) => {
        console.log(`📻 收到来自 ${playerId} 的音频流`);
        const [remoteStream] = event.streams;
        this.remoteStreams.set(playerId, remoteStream);
        
        if (this.onRemoteStreamReceived) {
          this.onRemoteStreamReceived(playerId, remoteStream);
        }
        
        // 开始监控这个连接的质量
        this.startConnectionQualityMonitoring(playerId, peerConnection);
      };
      
      // 处理ICE候选
      peerConnection.onicecandidate = (event) => {
        if (event.candidate) {
          // 通过信令服务器发送ICE候选
          this.sendSignalingMessage(playerId, {
            type: 'ice-candidate',
            candidate: event.candidate
          });
        }
      };
      
      // 处理连接状态变化
      peerConnection.onconnectionstatechange = () => {
        const state = peerConnection.connectionState;
        // 连接状态日志已移除以减少控制台输出
        
        if (this.onConnectionStateChanged) {
          this.onConnectionStateChanged(playerId, state);
        }
        
        // 连接失败或关闭时清理
        if (state === 'failed' || state === 'closed') {
          this.closePeerConnection(playerId);
        }
      };
      
      // 存储连接
      this.peerConnections.set(playerId, peerConnection);
      
      // 如果是发起方，创建offer
      if (isInitiator) {
        const offer = await peerConnection.createOffer();
        await peerConnection.setLocalDescription(offer);
        
        // 发送offer
        this.sendSignalingMessage(playerId, {
          type: 'offer',
          offer: offer
        });
      }
      
      console.log(`✅ 与 ${playerId} 的P2P连接已创建`);
      return peerConnection;
      
    } catch (error) {
      console.error(`创建与 ${playerId} 的P2P连接失败:`, error);
      throw error;
    }
  }
  
  /**
   * 处理信令消息
   */
  async handleSignalingMessage(fromPlayerId, message) {
    const peerConnection = this.peerConnections.get(fromPlayerId);
    
    if (!peerConnection) {
      console.warn(`收到来自 ${fromPlayerId} 的信令，但没有对应的连接`);
      return;
    }
    
    try {
      switch (message.type) {
        case 'offer': {
          await peerConnection.setRemoteDescription(message.offer);
          const answer = await peerConnection.createAnswer();
          await peerConnection.setLocalDescription(answer);
          
          // 发送answer
          this.sendSignalingMessage(fromPlayerId, {
            type: 'answer',
            answer: answer
          });
          break;
        }
          
        case 'answer':
          await peerConnection.setRemoteDescription(message.answer);
          break;
          
        case 'ice-candidate':
          await peerConnection.addIceCandidate(message.candidate);
          break;
          
        default:
          console.warn('未知的信令消息类型:', message.type);
      }
    } catch (error) {
      console.error('处理信令消息失败:', error);
    }
  }
  
  /**
   * 发送信令消息（需要外部实现）
   */
  sendSignalingMessage(toPlayerId, message) {
    // 这个方法需要在初始化时设置回调
    if (this.onSignalingMessage) {
      this.onSignalingMessage(toPlayerId, message);
    } else {
      console.warn('信令消息发送回调未设置');
    }
  }
  
  /**
   * 开始监控连接质量
   */
  startConnectionQualityMonitoring(playerId, peerConnection) {
    const monitorQuality = async () => {
      try {
        const stats = await peerConnection.getStats();
        let quality = 'good';
        let rtt = 0;
        let packetsLost = 0;
        let jitter = 0;
        
        stats.forEach(report => {
          if (report.type === 'inbound-rtp' && report.mediaType === 'audio') {
            packetsLost = report.packetsLost || 0;
            jitter = report.jitter || 0;
          } else if (report.type === 'candidate-pair' && report.state === 'succeeded') {
            rtt = report.currentRoundTripTime || 0;
          }
        });
        
        // 根据统计数据判断质量
        if (rtt > 0.3 || packetsLost > 50 || jitter > 0.1) {
          quality = 'poor';
        } else if (rtt > 0.1 || packetsLost > 10 || jitter > 0.05) {
          quality = 'fair';
        } else {
          quality = 'excellent';
        }
        
        // 更新质量信息
        this.connectionQualities.set(playerId, {
          quality,
          rtt: Math.round(rtt * 1000), // 转换为毫秒
          packetsLost,
          jitter: Math.round(jitter * 1000),
          timestamp: Date.now()
        });
        
        if (this.onConnectionQualityChanged) {
          this.onConnectionQualityChanged(playerId, {
            quality,
            rtt: Math.round(rtt * 1000),
            packetsLost,
            jitter: Math.round(jitter * 1000)
          });
        }
        
      } catch (error) {
        console.error(`监控 ${playerId} 连接质量失败:`, error);
      }
    };
    
    // 每5秒监控一次
    const timerId = setInterval(monitorQuality, 5000);
    this.simulationTimers.set(`quality-${playerId}`, timerId);
  }
  
  /**
   * 关闭与指定玩家的连接
   */
  closePeerConnection(playerId) {
    const peerConnection = this.peerConnections.get(playerId);
    if (peerConnection) {
      peerConnection.close();
      this.peerConnections.delete(playerId);
    }
    
    // 清理远程流
    this.remoteStreams.delete(playerId);
    
    // 清理连接质量信息
    this.connectionQualities.delete(playerId);
    
    // 清理定时器
    const qualityTimerId = this.simulationTimers.get(`quality-${playerId}`);
    if (qualityTimerId) {
      clearInterval(qualityTimerId);
      this.simulationTimers.delete(`quality-${playerId}`);
    }
    
    console.log(`🔌 与 ${playerId} 的连接已关闭`);
  }
  
  /**
   * 获取连接质量信息
   */
  getConnectionQuality(playerId) {
    return this.connectionQualities.get(playerId) || {
      quality: 'unknown',
      rtt: 0,
      packetsLost: 0,
      jitter: 0
    };
  }
  
  /**
   * 设置远程音频音量
   */
  setRemoteAudioVolume(playerId, volume) {
    const remoteStream = this.remoteStreams.get(playerId);
    if (!remoteStream) return;
    
    // 创建或获取音频元素
    let audioElement = document.getElementById(`remote-audio-${playerId}`);
    if (!audioElement) {
      audioElement = document.createElement('audio');
      audioElement.id = `remote-audio-${playerId}`;
      audioElement.autoplay = true;
      audioElement.style.display = 'none';
      document.body.appendChild(audioElement);
    }
    
    audioElement.srcObject = remoteStream;
    audioElement.volume = Math.max(0, Math.min(1, volume));
  }
  
  /**
   * 静音远程音频
   */
  muteRemoteAudio(playerId, muted) {
    const audioElement = document.getElementById(`remote-audio-${playerId}`);
    if (audioElement) {
      audioElement.muted = muted;
    }
  }
  
  // ================================
  // 房间级别的音频管理方法
  // ================================
  
  /**
   * 加入语音房间
   * @param {string} roomId 房间ID
   * @param {Array} participants 房间参与者ID列表
   * @param {string} roomType 房间类型：'public' 或 'private'
   */
  async joinVoiceRoom(roomId, participants = [], roomType = 'public') {
    try {
      console.log(`🚪 加入语音房间 ${roomId} (${roomType})，参与者:`, participants);
      
      // 初始化房间连接管理
      if (!this.roomConnections.has(roomId)) {
        this.roomConnections.set(roomId, new Map());
      }
      if (!this.roomStreams.has(roomId)) {
        this.roomStreams.set(roomId, new Map());
      }
      if (!this.roomConnectionQualities.has(roomId)) {
        this.roomConnectionQualities.set(roomId, new Map());
      }
      
      // 添加到当前房间列表
      this.currentRooms.add(roomId);
      
      // 如果是私聊房间，需要断开不在此房间的连接
      if (roomType === 'private') {
        await this.isolatePrivateRoom(roomId, participants);
      }
      
      // 与房间内的其他参与者建立连接
      for (const participantId of participants) {
        if (participantId !== this.currentPlayerId && !this.hasRoomConnection(roomId, participantId)) {
          await this.createRoomPeerConnection(roomId, participantId, true);
        }
      }
      
      // 更新向后兼容的全局映射（如果这是主要房间）
      if (roomType === 'public' || this.currentRooms.size === 1) {
        this.updateCompatibilityMappings(roomId);
      }
      
      // 触发事件
      if (this.onRoomJoined) {
        this.onRoomJoined(roomId);
      }
      
      console.log(`✅ 成功加入语音房间 ${roomId}`);
      
    } catch (error) {
      console.error(`❌ 加入语音房间 ${roomId} 失败:`, error);
      throw error;
    }
  }
  
  /**
   * 离开语音房间
   * @param {string} roomId 房间ID
   */
  async leaveVoiceRoom(roomId) {
    try {
      console.log(`🚪 离开语音房间 ${roomId}`);
      
      // 断开房间内的所有连接
      const roomConnections = this.roomConnections.get(roomId);
      if (roomConnections) {
        for (const [playerId, connection] of roomConnections) {
          connection.close();
          console.log(`🔌 断开与 ${playerId} 在房间 ${roomId} 中的连接`);
        }
      }
      
      // 清理房间数据
      this.roomConnections.delete(roomId);
      this.roomStreams.delete(roomId);
      this.roomConnectionQualities.delete(roomId);
      this.currentRooms.delete(roomId);
      
      // 清理房间相关的音频元素
      this.cleanupRoomAudioElements(roomId);
      
      // 更新向后兼容的全局映射
      this.updateCompatibilityMappingsAfterLeave(roomId);
      
      // 触发事件
      if (this.onRoomLeft) {
        this.onRoomLeft(roomId);
      }
      
      console.log(`✅ 成功离开语音房间 ${roomId}`);
      
    } catch (error) {
      console.error(`❌ 离开语音房间 ${roomId} 失败:`, error);
      throw error;
    }
  }
  
  /**
   * 隔离私聊房间（断开不相关的连接）
   * @param {string} privateRoomId 私聊房间ID
   * @param {Array} allowedParticipants 允许的参与者列表
   */
  async isolatePrivateRoom(privateRoomId, allowedParticipants) {
    console.log(`🔒 隔离私聊房间 ${privateRoomId}，允许的参与者:`, allowedParticipants);
    
    // 断开与非私聊成员的所有连接
    for (const [roomId, roomConnections] of this.roomConnections) {
      if (roomId !== privateRoomId) {
        for (const [playerId, connection] of roomConnections) {
          if (!allowedParticipants.includes(playerId)) {
            console.log(`🔌 断开与 ${playerId} 的连接（不在私聊房间 ${privateRoomId} 中）`);
            connection.close();
            roomConnections.delete(playerId);
            
            // 同时清理音频元素
            this.removePlayerAudioElement(playerId);
          }
        }
      }
    }
  }
  
  /**
   * 创建房间级别的P2P连接
   */
  async createRoomPeerConnection(roomId, playerId, isInitiator = false) {
    try {
      console.log(`🔗 在房间 ${roomId} 中与 ${playerId} 建立连接 (发起方: ${isInitiator})`);
      
      const peerConnection = new RTCPeerConnection(this.rtcConfig);
      
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => {
          peerConnection.addTrack(track, this.localStream);
        });
      }
      
      peerConnection.ontrack = (event) => {
        console.log(`📻 在房间 ${roomId} 中收到来自 ${playerId} 的音频流`);
        const [remoteStream] = event.streams;
        
        if (!this.roomStreams.has(roomId)) {
          this.roomStreams.set(roomId, new Map());
        }
        this.roomStreams.get(roomId).set(playerId, remoteStream);
        
        this.createPlayerAudioElement(playerId, remoteStream, roomId);
        
        if (this.onRoomStreamReceived) {
          this.onRoomStreamReceived(roomId, playerId, remoteStream);
        }
        
        if (this.onRemoteStreamReceived) {
          this.onRemoteStreamReceived(playerId, remoteStream);
        }
        
        this.startRoomConnectionQualityMonitoring(roomId, playerId, peerConnection);
      };
      
      peerConnection.onicecandidate = (event) => {
        if (event.candidate) {
          this.sendRoomSignalingMessage(roomId, playerId, {
            type: 'ice-candidate',
            candidate: event.candidate
          });
        }
      };
      
      peerConnection.onconnectionstatechange = () => {
        const state = peerConnection.connectionState;
        // 房间连接状态日志已移除以减少控制台输出
        
        if (this.onRoomConnectionStateChanged) {
          this.onRoomConnectionStateChanged(roomId, playerId, state);
        }
        
        if (this.onConnectionStateChanged) {
          this.onConnectionStateChanged(playerId, state);
        }
        
        if (state === 'failed' || state === 'closed') {
          this.closeRoomPeerConnection(roomId, playerId);
        }
      };
      
      if (!this.roomConnections.has(roomId)) {
        this.roomConnections.set(roomId, new Map());
      }
      this.roomConnections.get(roomId).set(playerId, peerConnection);
      
      if (isInitiator) {
        const offer = await peerConnection.createOffer();
        await peerConnection.setLocalDescription(offer);
        
        this.sendRoomSignalingMessage(roomId, playerId, {
          type: 'offer',
          offer: offer
        });
      }
      
      return peerConnection;
      
    } catch (error) {
      console.error(`❌ 在房间 ${roomId} 中与 ${playerId} 建立连接失败:`, error);
      throw error;
    }
  }
  
  /**
   * 关闭房间中的特定连接
   */
  closeRoomPeerConnection(roomId, playerId) {
    const roomConnections = this.roomConnections.get(roomId);
    if (roomConnections && roomConnections.has(playerId)) {
      roomConnections.get(playerId).close();
      roomConnections.delete(playerId);
    }
    
    const roomStreams = this.roomStreams.get(roomId);
    if (roomStreams && roomStreams.has(playerId)) {
      roomStreams.delete(playerId);
    }
    
    const roomQualities = this.roomConnectionQualities.get(roomId);
    if (roomQualities && roomQualities.has(playerId)) {
      roomQualities.delete(playerId);
    }
    
    this.removePlayerAudioElement(playerId);
    console.log(`🔌 已断开房间 ${roomId} 中与 ${playerId} 的连接`);
  }
  
  /**
   * 检查是否存在房间连接
   */
  hasRoomConnection(roomId, playerId) {
    const roomConnections = this.roomConnections.get(roomId);
    return roomConnections && roomConnections.has(playerId);
  }
  
  /**
   * 发送房间级别的信令消息
   */
  sendRoomSignalingMessage(roomId, targetPlayerId, message) {
    if (this.sendSignalingMessage) {
      this.sendSignalingMessage(targetPlayerId, {
        ...message,
        roomId: roomId,
        sourceRoomId: roomId
      });
    }
  }
  
  /**
   * 创建玩家音频元素（支持房间标识）
   */
  createPlayerAudioElement(playerId, stream, roomId = 'default') {
    const audioId = `remote-audio-${playerId}-${roomId}`;
    
    const existingAudio = document.getElementById(audioId);
    if (existingAudio) {
      existingAudio.remove();
    }
    
    const audioElement = document.createElement('audio');
    audioElement.id = audioId;
    audioElement.srcObject = stream;
    audioElement.autoplay = true;
    audioElement.playsInline = true;
    audioElement.volume = this.getPlayerVolume(playerId);
    audioElement.dataset.roomId = roomId;
    audioElement.dataset.playerId = playerId;
    audioElement.style.display = 'none';
    
    document.body.appendChild(audioElement);
    console.log(`🔊 为玩家 ${playerId} 在房间 ${roomId} 中创建音频元素`);
  }
  
  /**
   * 移除玩家音频元素
   */
  removePlayerAudioElement(playerId) {
    document.querySelectorAll(`[data-player-id="${playerId}"]`).forEach(element => {
      element.remove();
    });
    console.log(`🔇 移除玩家 ${playerId} 的所有音频元素`);
  }
  
  /**
   * 清理特定房间的音频元素
   */
  cleanupRoomAudioElements(roomId) {
    document.querySelectorAll(`[data-room-id="${roomId}"]`).forEach(element => {
      element.remove();
    });
    console.log(`🧹 清理房间 ${roomId} 的所有音频元素`);
  }
  
  /**
   * 开始房间连接质量监控
   */
  startRoomConnectionQualityMonitoring(roomId, playerId, connection) {
    const monitorQuality = async () => {
      try {
        const stats = await connection.getStats();
        let quality = 'unknown';
        let ping = 0;
        
        stats.forEach((report) => {
          if (report.type === 'candidate-pair' && report.state === 'succeeded') {
            ping = report.currentRoundTripTime * 1000;
            
            if (ping < 100) quality = 'excellent';
            else if (ping < 200) quality = 'good';
            else if (ping < 400) quality = 'fair';
            else if (ping < 800) quality = 'poor';
            else quality = 'bad';
          }
        });
        
        if (!this.roomConnectionQualities.has(roomId)) {
          this.roomConnectionQualities.set(roomId, new Map());
        }
        this.roomConnectionQualities.get(roomId).set(playerId, { quality, ping });
        
        this.connectionQualities.set(playerId, { quality, ping });
        
        if (this.onConnectionQualityChanged) {
          this.onConnectionQualityChanged(playerId, quality, ping);
        }
        
      } catch (error) {
        console.warn(`连接质量监控失败 (房间 ${roomId}, 玩家 ${playerId}):`, error);
      }
    };
    
    const intervalId = setInterval(monitorQuality, 5000);
    
    connection.addEventListener('connectionstatechange', () => {
      if (connection.connectionState === 'closed' || connection.connectionState === 'failed') {
        clearInterval(intervalId);
      }
    });
  }
  
  /**
   * 更新向后兼容的全局映射
   */
  updateCompatibilityMappings(primaryRoomId) {
    const roomConnections = this.roomConnections.get(primaryRoomId);
    const roomStreams = this.roomStreams.get(primaryRoomId);
    const roomQualities = this.roomConnectionQualities.get(primaryRoomId);
    
    if (roomConnections) {
      this.peerConnections.clear();
      for (const [playerId, connection] of roomConnections) {
        this.peerConnections.set(playerId, connection);
      }
    }
    
    if (roomStreams) {
      this.remoteStreams.clear();
      for (const [playerId, stream] of roomStreams) {
        this.remoteStreams.set(playerId, stream);
      }
    }
    
    if (roomQualities) {
      this.connectionQualities.clear();
      for (const [playerId, quality] of roomQualities) {
        this.connectionQualities.set(playerId, quality);
      }
    }
  }
  
  /**
   * 离开房间后更新向后兼容映射
   * @param {string} leftRoomId 离开的房间ID
   */
  updateCompatibilityMappingsAfterLeave(leftRoomId) {
    console.log('Updating compatibility mappings after leaving room:', leftRoomId);
    if (this.currentRooms.size > 0) {
      const primaryRoomId = Array.from(this.currentRooms)[0];
      this.updateCompatibilityMappings(primaryRoomId);
    } else {
      this.peerConnections.clear();
      this.remoteStreams.clear();
      this.connectionQualities.clear();
    }
  }
  
  /**
   * 获取当前所在的房间列表
   */
  getCurrentRooms() {
    return Array.from(this.currentRooms);
  }
  
  /**
   * 获取房间中的所有连接
   */
  getRoomConnections(roomId) {
    return this.roomConnections.get(roomId) || new Map();
  }
  
  /**
   * 获取房间中的所有音频流
   */
  getRoomStreams(roomId) {
    return this.roomStreams.get(roomId) || new Map();
  }
  
  /**
   * 获取玩家音量（向后兼容）
   * @param {string} playerId 玩家ID
   */
  getPlayerVolume(playerId) {
    console.log('Getting volume for player:', playerId);
    // 这里可以从配置中获取特定玩家的音量，暂时返回默认值
    return 0.8;
  }
  
  /**
   * 设置当前玩家ID
   * @param {string} playerId 当前玩家ID
   */
  setCurrentPlayerId(playerId) {
    this.currentPlayerId = playerId;
  }

  /**
   * 销毁语音引擎
   */
  destroy() {
    // 关闭所有房间的P2P连接
    this.roomConnections.forEach((roomConnections, roomId) => {
      roomConnections.forEach((connection, playerId) => {
        connection.close();
        console.log(`🔌 关闭房间 ${roomId} 中与 ${playerId} 的连接`);
      });
    });
    
    // 清理房间数据
    this.roomConnections.clear();
    this.roomStreams.clear();
    this.roomConnectionQualities.clear();
    this.currentRooms.clear();
    
    // 关闭所有P2P连接（向后兼容）
    this.peerConnections.forEach((_, playerId) => {
      this.closePeerConnection(playerId);
    });
    
    // 停止本地流
    if (this.localStream) {
      this.localStream.getTracks().forEach(track => track.stop());
      this.localStream = null;
    }
    
    // 关闭音频上下文
    if (this.audioContext && this.audioContext.state !== 'closed') {
      this.audioContext.close();
    }
    
    // 清理所有定时器
    this.simulationTimers.forEach(timerId => clearInterval(timerId));
    this.simulationTimers.clear();
    
    // 清理音频元素
    document.querySelectorAll('[id^="remote-audio-"]').forEach(element => {
      element.remove();
    });
    
    console.log('🔥 语音引擎已销毁');
  }
}

export default VoiceEngine;